/*------------------------------------------------------------------------------
 * @file    U8X8CB.C
 * @author  嵌入式王子
 * @email   donminedm@163.com
 * @date    2024/07/17 21:48:15
 * @brief   开源的嵌入式软件包，本人不对此代码负责任
 * -----------------------------------------------------------------------------*/
#include "u8x8cb.h"
#include "log.h"

static uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
    /* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
    static uint8_t buffer[OLED_BUFF_SIZE];
    static uint8_t buff_index;
    uint8_t *data;
    switch (msg)
    {
    case U8X8_MSG_BYTE_INIT:
    {
        /* add your custom code to init i2c subsystem */
        // MX_I2C1_Init();
    }
    break;
    case U8X8_MSG_BYTE_START_TRANSFER:
    {
        buff_index = 0; // 开始传输
    }
    break;

    case U8X8_MSG_BYTE_SEND:
    {
        data = (uint8_t *)arg_ptr;
        while (arg_int > 0)
        {
            buffer[buff_index++] = *data;
            data++;
            arg_int--;
        }
    }
    break;

    case U8X8_MSG_BYTE_END_TRANSFER:
    {
        // 将拷贝的数据发送
        if (HAL_I2C_Master_Transmit(OLED_HANDLE, OLED_ADDRESS, buffer, buff_index, OLED_MSG_TIMEOUT) != HAL_OK)
        {
            logw("timeout");
            return 0;
        }
    }
    break;

    case U8X8_MSG_BYTE_SET_DC:
        break;

    default:
        return 0;
    }

    return 1;
}

static uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
    switch (msg)
    {
    case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds
        __NOP();
        break;
    case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds
        OLED_DELAY_US(10);
        break;
    case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
        OLED_DELAY_MS(1);
        break;
    case U8X8_MSG_DELAY_I2C: // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz
        OLED_DELAY_MS(5);
        break;                    // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us
    case U8X8_MSG_GPIO_I2C_CLOCK: // arg_int=0: Output low at I2C clock pin
        break;                    // arg_int=1: Input dir with pullup high for I2C clock pin
    case U8X8_MSG_GPIO_I2C_DATA:  // arg_int=0: Output low at I2C data pin
        break;                    // arg_int=1: Input dir with pullup high for I2C data pin
    case U8X8_MSG_GPIO_MENU_SELECT:
        u8x8_SetGPIOResult(u8x8, /* get menu select pin state */ 0);
        break;
    case U8X8_MSG_GPIO_MENU_NEXT:
        u8x8_SetGPIOResult(u8x8, /* get menu next pin state */ 0);
        break;
    case U8X8_MSG_GPIO_MENU_PREV:
        u8x8_SetGPIOResult(u8x8, /* get menu prev pin state */ 0);
        break;
    case U8X8_MSG_GPIO_MENU_HOME:
        u8x8_SetGPIOResult(u8x8, /* get menu home pin state */ 0);
        break;
    default:
        u8x8_SetGPIOResult(u8x8, 1); // default return value
        break;
    }
    return 1;
}

void u8g2Init(u8g2_t *u8g2)
{
    /*
    *u8g2 实例化的u8g2  对象的地址
    *rotation:旋转方向 对应参数如下 具体效果可以自己测试
    *	U8G2_R0
        U8G2_R1
        U8G2_R2
        U8G2_R3
        U8G2_MIRROR
        U8G2_MIRROR_VERTICAL
    *byte_cb:字节传输函数 是上面我们适配的u8x8_byte_hw_i2c
    *gpio_and_delay_cb:延时函数 是上面我们适配的u8g2_stm32_delay
    */
    u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_hw_i2c, u8x8_gpio_and_delay);
    // u8g2_Setup_sh1106_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_hw_i2c, u8x8_gpio_and_delay);
    u8g2_InitDisplay(u8g2);                         // 初始化
    u8g2_SetPowerSave(u8g2, 0);                     // 设置电源模式
    u8g2_ClearBuffer(u8g2);                         // 清空缓冲区
    u8g2_SetFont(u8g2, u8g2_font_wqy16_t_chinese1); // 设置字体

    logi("u8g2 init over");
}